#pragma once

#include "collectionimage.h"

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <fstream>
#include <vector>

/** 
 * \ingroup ti6
 *
 * \brief
 * Instances of the Collection class store all data associated to an image
 * collection. The filenames and thumbnails are stored in instances of
 * CollectionImage. All metadata is directly stored in XML. LibXML is used
 * to read and edit this data.
 * The Collection class is used by CollectionBox, CollectionTab and
 * MetaDataDialog.
 *
 * Copyright (c) Academie voor ICT en Media 2007 - 2008
 */
class Collection
{
public:
	/**
	 \brief
	 Default constructor, creates an empty collection.
	 */
	Collection();

	/**
	 \brief
	 Copy constructor, creates a deep copy of the specified collection.

	 \param Collection& The collection to copy.
	 */
	Collection( const Collection& );

	/**
	 \brief
	 Destruct the collection. This does not save the collection to disk.
	 */
	~Collection();

	/**
	 \brief
	 Copy the specified collection to this instance. This will invalidate
	 the previous contents of this instance.
	 
	 \param Collection& The collection to copy.
	 \return This instance.
	 */
	Collection& operator =( const Collection& );

	/**
	 \brief
	 Add an image to the collection. The number of this image will be
	 equal to size() before the call to addImage(). This function does not
	 check whether the image is already present in the collection.
	 
	 \param &image The image to add to the collection.
	 */
	void addImage( CollectionImage &image );

	/**
	 \brief
	 Get an image from this collection. The first image has the number 0.
	 The value of num must thus be smaller than the value returned by size().
	 
	 \param num The number of the image.
	 \return A reference to the collection image.
	 */
	CollectionImage& getImage( unsigned int num );

	/**
	 \brief
	 Get the number of images in this collection.
	 
	 \return The number of images.
	 */
	unsigned int size() const;

	/**
	 \brief
	 Set the metadata for an image in this collection. The value of
	 imageNum must be smaller than the value returned by size().
	 
	 \param imageNum The number of the image.
	 \param *xml The metadata, in xml. This value is passed as an
	   UTF-8 string.
	 */
	void setMetaData( int imageNum, xmlChar *xml );

	/**
	 \brief
	 Get the metadata for an image in this collection. The value of
	 imageNum must be smaller than the value returned by size().
	 
	 \param imageNum The number of the image.
	 \return The metadata, in xml. This value is returned as an
	   UTF-8 string.
	 */
	xmlChar* metaData( int imageNum );
	
	/**
	 \brief
	 Make a selection of the images in this collection. This method
	 is called as a response to a user interface command.
	 */
	void search();

	/**
	 \brief
	 Save the collection to disk. The collection will be saved in XML
	 format and does not contain the images itself (only the filenames).
	 
	 \param *file The filename for the collection file.
	 \return True is returned if the action was successfull, false
	   is returned otherwise.
	 */
	bool save( char *file );

	/**
	 \brief
	 Get the number of the selected image.
	 
	 \return The number of the selected image. If there is no selection,
	   -1 is returned.
	 */
	int selected() const;

	/**
	 \brief
	 Set the selected image. To void the selection, use the number -1.
	 
	 \param selected The number of the image to select.
	 */
	void setSelected( int selected );
private:
	/**
	 The xml document in which all metadata is stored.
	 */
	xmlDoc *_xmlDoc;

	/**
	 The collection of images.
	 */
	std::vector<CollectionImage> _images;

	/**
	 The number of the selected image. A value of -1 means there is
	 no current selection.
	 */
	int _selected;
};
